import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';
import { Reflector } from '@nestjs/core';
import { RedisService } from '../redis/redis.service';
import Constants from '../common/constants';
import RoleEnum from '../role/entities/RoleEnum';
import { AdminForbiddenException } from '../exception/admin-forbidden.exception';
import { SuperAdminForbiddenException } from '../exception/super-admin-forbidden.exception';
import { Permission } from './entities/permission.entity';
import { NoPermissionException } from '../exception/no-permission.exception';

@Injectable()
export class PermissionGuard implements CanActivate {
  constructor(
    private reflector: Reflector,
    private readonly redisService: RedisService,
  ) {}

  async canActivate(context: ExecutionContext) {
    const permission = this.reflector.get<string>(
      'permission',
      context.getHandler(),
    );
    // 权限注解没有添加权限，则允许请求允许每个请求继续进行
    if (!permission) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = JSON.parse(
      await this.redisService.get(`${request.headers[Constants.Access_Token]}`),
    );
    console.log(
      'role.guard.ts-canActivate-user.role.roleName',
      permission,
      user.role.permissions.map(
        (permissions: Permission) => permissions.permCode,
      ),
    );
    return this.hasPermissions(
      user.role.permissions.map(
        (permissions: Permission) => permissions.permCode,
      ),
      permission,
    );
  }

  /**
   * 判断是否有对应的权限
   * @param currentPermissions 用户已有的权限
   * @param needPermission 访问接口必须要的权限
   */
  hasPermissions = (currentPermissions: string[], needPermission: string) => {
    // 当前有 user:all,role:all

    // 需要权限 user:select
    const prefixPerm = needPermission.split(':')[0];

    console.log(prefixPerm, 'prefixPerm');

    if (currentPermissions.includes(`${prefixPerm}:all`)) return true;
    if (currentPermissions.includes(needPermission)) return true;
    throw new NoPermissionException(needPermission);
  };
}
